In a multi-threaded environment, a program may include two or more threads that interact with a software component in a concurrent manner. A developer will attempt to design such a component so that it exhibits correct behavior in this environment. Deviations from intended behavior often yield erroneous results, such as an indication that a queue is empty when, in fact, it is not. On the other hand, a component which appears to behave in a desired manner is said to be “thread safe.”
The industry has proposed different ways of defining and testing thread safety. These techniques, however, have one or more drawbacks. One such shortcoming is inaccurate and/or imprecise results. For example, some atomicity checking techniques suffer from false alarms, reporting concurrency-related errors even on correct implementations. Other techniques (such as data-race freedom techniques) may provide a restrictive definition of thread safety that fails to identify legitimate concurrency-related errors.
Still other techniques are complex and burdensome. For example, some techniques rely on the user to manually annotate the source code associated with a component by identifying linearization points within the code. A component is considered linearizable if each operation appears to take effect atomically at these manually-defined linearization points, where each such point is temporally located between the time of operation call and the time of operation return. However, this approach is not fully satisfactory. First, the user may provide incorrect annotations, which may lead to false alarms during the test. Second, the user may not be effective in using this approach if he or she does not possess detailed knowledge of the source code of the component. The user may also be at a disadvantage if he or she does not have an adequate understanding of the theory on which this testing approach is based. Third, the location of the linearization points may depend on dynamic conditions that are not statically known; in these circumstances, the user may need to resort to nontrivial annotation techniques to identify the locations of linearization points.
For at least these representative reasons, it is considered a difficult task to build and test components that behave in a manner that is considered thread safe. Indeed, there is even lack of consensus at to what thread safety may entail in different environments.